package com.lk.service;

import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;

import java.sql.SQLException;


/**
 * @author : lk
 * @date 2021/11/18 14:19
 * @description : TODO
 * @since 1.0
 **/

public interface MyService {

    /**
     * 虽然注解 使用方便但是可配置的东西太少
     * 如果想使用spring-retry强大的策略机制，并需定制化RetryTemplate。
     * RetryTemplate 对象可以设置重试策略、补偿策略、重试监听等属性。
     *
     * 当出现运行时异常时 重试可能发生多达三次，在重试之间延迟一秒钟。
     * 添加上 @Recover时 当 Retryable出现异常 后 会回退到Recover 上
     * 如果有返回值 返回的值也是Recover 返回出来的内容
     * 要保证 Retryable标注的方法的返回值 和Recover时 的一致
     * 并且 Recover 要清楚的知道捕获的时那个异常
     *
     * @param sql
     * @Retryable 中参数的解释
     * value：标注哪些异常
     * label;统计报告的唯一标签。 如果未提供，调用者可以选择忽略它，或提供默认值
     * stateful:标志表示重试是有状态的：即重新抛出异常，
     * 但重试策略以相同的策略应用于具有相同参数的后续调用。 如果为 false，则不会重新抛出可重试的异常
     * maxAttempts: 最大重试次数
     * backoff:指定用于重试此操作的退避属性。 默认值是一个没有属性的简单Backoff规范 - 请参阅它的文档以了解默认值
     * @Backoff :
     * delay  延迟100ms
     * multiplier即指定延迟倍数
     */
    @Retryable(value = RuntimeException.class, label = "retryService",
            stateful = false, maxAttempts = 3, backoff = @Backoff(delay = 100))
    String retryService(String sql) throws RuntimeException;

    @Recover
    String retryHui(RuntimeException e, String sql);
}
